package lumis.portal.presentation.tag.el;

import java.util.HashSet;
import java.util.Set;

import lumis.portal.presentation.core.IPageRenderer;
import lumis.portal.presentation.core.LayoutFilePage;
import lumis.util.HtmlUtil;
import lumis.util.XmlUtil;

import org.apache.wicket.Component;
import org.apache.wicket.behavior.AbstractBehavior;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.util.value.IValueMap;

/**
 * Behavior used to process tags with EL namespace attributes.
 *
 * @version $Revision: 13093 $ $Date: 2011-05-28 18:40:18 -0300 (Sat, 28 May 2011) $
 * @since 6.0.0
 */
@SuppressWarnings("serial")
class ELAttributeBehavior extends AbstractBehavior
{	
	private static final String NAMESPACE_SEPARATOR = ":";
	
	private boolean stripLayoutFileTagsAndAttributes;	
	private String attributePrefix;
	
	ELAttributeBehavior(boolean stripLayoutFileTagsAndAttributes, String namespacePrefix)
	{
		this.stripLayoutFileTagsAndAttributes = stripLayoutFileTagsAndAttributes;
		this.attributePrefix = namespacePrefix + NAMESPACE_SEPARATOR;
	}
	
	@Override
	public void onComponentTag(Component component, ComponentTag tag)
	{
		IPageRenderer pageRenderer = ((LayoutFilePage) component.getPage()).getPageRenderer();
		
		// process tag attributes
		IValueMap tagAttributesMap = tag.getAttributes();		
		Set<String> attributeNamesSet = new HashSet<String>(tag.getAttributes().keySet());
		for (String namespacedAttributeName : attributeNamesSet)
		{
			if (isELAttribute(namespacedAttributeName))
			{
				String attributeName = namespacedAttributeName.substring(attributePrefix.length());
				String value = tagAttributesMap.getString(namespacedAttributeName);
				
				// remove the el namespace attribute
				if (this.stripLayoutFileTagsAndAttributes)
				{	
					tagAttributesMap.remove(namespacedAttributeName);					
				}
				
				// evaluate the EL. Decodes/encodes the HTML, 
				// because tag attribute read/write methods does no conversion
				String decodedValue = HtmlUtil.decode(value);
				CharSequence result = pageRenderer.evaluateEL(decodedValue);
				if (result != null)
				{
					// update attribute in the tag
					String evaluatedValue = XmlUtil.encodeXml(result.toString());
					tag.put(attributeName, evaluatedValue);
				}
				else
				{
					tag.remove(attributeName);
				}
				
				tag.setModified(true);
			}
		}
	}
	
	/**
	 * Checks if an attribute is an EL attribute (needs evaluation).
	 * @param attributeName	attribute's name.
	 * @return	true if the attribute needs to be evaluated, otherwise returns
	 * 			false.
	 * @since 6.0.0
	 */
	private boolean isELAttribute(String attributeName)
	{		
		return (attributeName.startsWith(this.attributePrefix));
	}
}